/*
接受一个tcp请求，简简单单发送发送一个http响应报文
*/
#include <string>
#include <sys/socket.h>
#include <sys/stat.h> 
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

using namespace std;
int main(int argc, char* argv[]){
    if(argc < 3){
        printf("need filename ip-address port\n");
        return 1;
    }
    //ip地址
    char *ip = argv[1];
    //端口
    int port = atoi(argv[2]);
    //创建socket,ipv4.tcp
    int listenfd = socket(PF_INET, SOCK_STREAM, 0);
    if(listenfd == -1){
        printf("Create socket error %d", errno);
        return 1;
    }
    //命名socket
    //创建ipv4地址
    struct sockaddr_in m_addr;
    bzero(&m_addr, sizeof(m_addr));
    m_addr.sin_family = AF_INET;
    inet_pton(AF_INET, ip, &m_addr.sin_addr);
    m_addr.sin_port = htons(port);
    //绑定
    int ret = bind(listenfd, (struct sockaddr*)&m_addr, sizeof(m_addr));
    if(ret == -1){
        printf("Socket bind error %d", ret);
        return 1;
    }
    //监听
    ret = listen(listenfd, 100);
    if(ret == -1){
        printf("Listen error %d", ret);
        return 1;
    }
    while(1){
        struct sockaddr_in addr;
        socklen_t addrlen = sizeof(addr);
        int new_con = accept(listenfd, (sockaddr *)&addr, &addrlen);
        if(new_con == -1){
            printf("accept error, errno = %d",errno);
            continue;
        } else {
            printf("accept %d success\n", new_con);
        }
        string html_file = "welcome.html";
        int fd = open(html_file.c_str(), O_RDONLY);
        struct stat file_stat;
        stat(html_file.c_str(), &file_stat);
        void *html_ = mmap(nullptr, file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);

        string buf_w = "HTTP/1.1 200 OK\r\n"
                        "Content-Type: text/html; charset=UTF-8\r\n"
                        "Connection: close\r\n"
                        "Date: Fri, 23 Nov 2018 02:01:05 GMT\r\n"
                        "Content-Length: " + to_string(file_stat.st_size) + "\r\n"
                        "\r\n";
        buf_w += (char *)html_;

        printf("send %d bytes\n", send(new_con, (void*)buf_w.c_str(), buf_w.size(), 0));
        munmap(html_, file_stat.st_size);
        

        sleep(2);
        close(new_con);
    }
    
  
    return 0;
}
